package com.wizo.csb;

import java.util.Properties;

import com.wizo.csb.records.Records;

/**
 * One experiment scenario. One object of this type will
 * be instantiated and shared among all client thread. This class
 * should be constructed using no-argument constructor, so we can
 * load it dynamically. Any argument-based initialization should be
 * done by init().
 *  
 * @author ywu70
 *
 */
public abstract class Workload {

	/**
	 * Initialize the scenario. Create any generators and other shared objects here.
	 * Called once, in the main client thread, before any operations are started.
	 */
	public void init(Properties p) throws WorkloadException{
		
	}
	
	/**
	 * Initialize any state for a particular client thread. Since the scenario object
	 * will be shared among all threads, this is the place to create any state that is specific
	 * to one thread. To be clear, this means the returned object should be created anew on each
	 * call to initThread(); do not return the same object multiple times.
	 * 
	 * The returned object will be passed to invocations of doRead() and doWrite() for this thread.
	 * There should be no side effects from this call; all state should be encapsulated in the
	 * returned object. If you have no state to retain for this thread, return null. (But if you have
	 * no state to retain for this thread, probably you don't need to override initThread().) 
	 * 
	 * Not decide yet:
	 * @return false if the workload knows it is done for this thread. Client will terminate the thread.
	 * return true otherwise.
	 */
	public Object initThread(Properties p, int myThreadID, int threadCount) throws WorkloadException{
		return null;
	}
	
	/**
	 * Cleanup the scenario. Called once, in the main client thread, after all operations have completed.
	 */
	public void cleanup() throws WorkloadException{
		
	}
	
	/**
	 * Do one create operation.
	 * Because it will be called concurrently from multiple client threads, this
	 * function must be thread safe. However, avoid synchronized, or the threads will block waiting for
	 * each other, and it will be difficult to reach the target throughput. Ideally, this function would 
	 * have no side effects other than storage operations and mutations on threadState. Mutation to 
	 * threadState do not need to be synchronized, since each thread has its own threadState instance.
	 */
	public abstract boolean doCreate(Records measurements, Storage storage);
	
	/**
	 * Do one transaction operation.
	 * Because it will be called concurrently from multiple client threads, this
	 * function must be thread safe. However, avoid synchronized, or the threads will block waiting for
	 * each other, and it will be difficult to reach the target throughput. Ideally, this function would 
	 * have no side effects other than storage operations and mutations on threadState. Mutation to 
	 * threadState do not need to be synchronized, since each thread has its own threadState instance.
	 */
	public abstract boolean doTransaction(Records measurements, Storage storage, String container);
	
	
}
